home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 06 - 1990 / 06.08 Aug 90 / LSObjectShell / StdScroll.p < prev    next >
Encoding:
Text File  |  1989-10-15  |  9.1 KB  |  371 lines  |  [TEXT/PJMM]

  1. UNIT StdScroll;
  2. {***********************************}
  3. INTERFACE
  4.  
  5.     USES
  6.         MemTypes, QuickDraw, OSIntf, ToolIntf, PackIntf, MacPrint, ObjIntf, GlobalStuff, MyDocuments;
  7.  
  8.     TYPE
  9.         TScrollBar = OBJECT(TObject)
  10.                 fCtlHdl: ControlHandle;
  11.                 oDocument: TDocument;
  12.                 FUNCTION ScrollMax (vBar, vMargin: Integer): Integer;
  13.                 PROCEDURE DoNew (vBar: Integer;
  14.                                             vWPtr: WindowPtr;
  15.                                             vRect: Rect);
  16.                 PROCEDURE ClickInSBar (vCtlItem: Integer;
  17.                                             vPt: Point);
  18.                 PROCEDURE SetupAutoScroll (vSBars: Integer);
  19.                 PROCEDURE Adjust;
  20.                 PROCEDURE ReDraw (vRect: Rect);
  21.                 PROCEDURE Activate;
  22.             END;
  23.  
  24.     PROCEDURE InitAutoScroll (oDoc: TDocument);
  25.  
  26. {***********************************}
  27. IMPLEMENTATION
  28.  
  29.     VAR
  30.         uHHdl: ControlHandle;
  31.         uVHdl: ControlHandle;
  32.         uSBars: Integer;
  33.         oDoc: TDocument;
  34.         uScrollDelay, uDelay: LongInt;
  35.  
  36. {========================================}
  37.     FUNCTION TScrollBar.ScrollMax (vBar, vMargin: Integer): Integer;
  38.         VAR
  39.             vDocWidth: Integer;
  40.             vDocHeight: Integer;
  41.             vMax: Integer;
  42.  
  43.     BEGIN
  44.         WITH oDocument.fDocRect DO
  45.             BEGIN
  46.                 vDocWidth := right - left;
  47.                 vDocHeight := bottom - top;
  48.             END;
  49.         vMax := 0;
  50.         WITH oDocument.fViewRect DO
  51.             CASE vBar OF
  52.                 kHBar: 
  53.                     vMax := vDocWidth - (right - left) + vMargin;
  54.                 kVBar: 
  55.                     vMax := vDocHeight - (bottom - top) + vMargin;
  56.             END;
  57.         IF vMax < 0 THEN
  58.             vMax := 0;
  59.         ScrollMax := vMax;
  60.     END; {ScrollMax}
  61.  
  62. {----------------------------------------}
  63.     PROCEDURE TScrollBar.DoNew (vBar: Integer;
  64.                                     vWPtr: WindowPtr;
  65.                                     vRect: Rect);
  66.         VAR
  67.             vTitle: Str255;
  68.             vVisible: BOOLEAN;
  69.             vCtlValue: Integer;
  70.             vCtlMin: Integer;
  71.             vCtlMax: Integer;
  72.             vProcID: Integer;
  73.             vRefVal: longint;
  74.  
  75.     BEGIN
  76.         vTitle := '';
  77.         vVisible := TRUE;
  78.         vCtlValue := 0;
  79.         vCtlMin := 0;
  80.         vCtlMax := ScrollMax(vBar, 0);
  81.         vProcID := scrollBarProc;
  82.         vRefVal := vBar;
  83.         fCtlHdl := NewControl(vWPtr, vRect, vTitle, vVisible, vCtlValue, vCtlMin, vCtlMax, vProcID, vRefVal);
  84.     END; {DoNew}
  85.  
  86. {----------------------------------------}
  87.     PROCEDURE ScrollContent (vCtlHdl: ControlHandle);
  88.         VAR
  89.             vCtlValue: Integer;
  90.             vDocRect: Rect;
  91.             vDeltaH, vDeltaV: Integer;
  92.             vUpdateRgn: RgnHandle;
  93.  
  94.     BEGIN
  95.         HLock(Handle(oDoc));
  96.         WITH oDoc DO
  97.             BEGIN
  98.                 vCtlValue := GetCtlValue(vCtlHdl);
  99.                 SetClip(fViewRgn);
  100.                 vDeltaH := 0;
  101.                 vDeltaV := 0;
  102.                 vUpdateRgn := NewRgn;
  103.                 CASE GetCRefCon(vCtlHdl) OF
  104.                     kHBar: 
  105.                         vDeltaH := fViewRect.left - fDocRect.left - vCtlValue;
  106.                     kVBar: 
  107.                         vDeltaV := fViewRect.top - fDocRect.top - vCtlValue;
  108.                 END;
  109.                 vDocRect := fDocRect;
  110.                 OffsetRect(vDocRect, vDeltaH, vDeltaV);
  111.                 fDocRect := vDocRect;
  112.                 ScrollRect(fViewRect, vDeltaH, vDeltaV, vUpdateRgn);
  113.                 SetClip(vUpdateRgn);
  114.                 Update;
  115.                 ClipRect(thePort^.portRect);
  116.                 DisposeRgn(vUpdateRgn);
  117.             END;
  118.         HUnlock(Handle(oDoc));
  119.     END;    {ScrollContent}
  120.  
  121. {-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -}
  122.     PROCEDURE DoScroll (vCtlHdl: ControlHandle;
  123.                                     vPart: Integer);
  124.         VAR
  125.             vCtlValue: Integer;
  126.             vCtlMax: Integer;
  127.             vCtlMin: Integer;
  128.             vSize: Integer;
  129.             vPageSize: Integer;
  130.             vAmount: Integer;
  131.  
  132.     BEGIN
  133.         vCtlValue := GetCtlValue(vCtlHdl);
  134.         vCtlMax := GetCtlMax(vCtlHdl);
  135.         vCtlMin := GetCtlMin(vCtlHdl);
  136.         vAmount := 0;
  137.         IF oDoc.fDocType = kTextDoc THEN
  138.             vSize := oDoc.fTextHdl^^.lineHeight
  139.         ELSE
  140.             vSize := 5;
  141.  
  142.         WITH oDoc.fViewRect DO
  143.             CASE GetCRefCon(vCtlHdl) OF
  144.                 kHBar: 
  145.                     vPageSize := (right - left) DIV 2;
  146.                 kVBar: 
  147.                     vPageSize := ((bottom - top) DIV vSize - 1) * vSize
  148.             END;
  149.  
  150.         CASE vPart OF
  151.             inUpButton: 
  152.                 IF vCtlValue > vCtlMin THEN
  153.                     vAmount := -vSize;
  154.             inDownButton: 
  155.                 IF vCtlValue < vCtlMax THEN
  156.                     vAmount := +vSize;
  157.             inPageUp: 
  158.                 IF vCtlValue > vCtlMin THEN
  159.                     vAmount := -vPageSize;
  160.             inPageDown: 
  161.                 IF vCtlValue < vCtlMax THEN
  162.                     vAmount := +vPageSize;
  163.             OTHERWISE
  164.         END;
  165.         IF vAmount <> 0 THEN
  166.             BEGIN
  167.                 SetCtlValue(vCtlHdl, vCtlValue + vAmount);
  168.                 ScrollContent(vCtlHdl);
  169.                 IF uScrollDelay > 0 THEN
  170.                     uScrollDelay := uScrollDelay - 5
  171.                 ELSE
  172.                     uScrollDelay := 0;
  173.                 Delay(uScrollDelay, uDelay);
  174.             END;
  175.     END; {DoScroll}
  176.  
  177. {-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -}
  178.     PROCEDURE TScrollBar.ClickInSBar (vCtlItem: Integer;
  179.                                     vPt: Point);
  180.     BEGIN
  181.         oDoc := self.oDocument;
  182.         CASE vCtlItem OF
  183.             inUpButton..inPageDown: 
  184.                 BEGIN
  185.                     uScrollDelay := kScrollDelay;
  186.                     vCtlItem := TrackControl(fCtlHdl, vPt, @DoScroll);
  187.                 END;
  188.             inThumb: 
  189.                 BEGIN
  190.                     vCtlItem := TrackControl(fCtlHdl, vPt, NIL);
  191.                     ScrollContent(fCtlHdl);
  192.                 END;
  193.         END;
  194.     END; {ClickInSBar}
  195.  
  196. {----------------------------------------}
  197.     FUNCTION DoAutoScroll: BOOLEAN;
  198.         VAR
  199.             vOldClip: RgnHandle;
  200.             vPt: Point;
  201.             vViewRect: Rect;
  202.  
  203.     BEGIN
  204.         vOldClip := NewRgn;
  205.         GetClip(vOldClip);
  206.         ClipRect(thePort^.portRect);
  207.         GetMouse(vPt);
  208.         vViewRect := oDoc.fViewRgn^^.rgnBBox;
  209.         IF uSBars IN [kHScroll, kScroll, kHScrollZoom, kScrollZoom] THEN
  210.             IF vPt.h < vViewRect.left THEN
  211.                 DoScroll(uHHdl, InUpButton)
  212.             ELSE IF vPt.h > vViewRect.right THEN
  213.                 DoScroll(uHHdl, InDownButton);
  214.         IF uSBars IN [kVScroll, kScroll, kVScrollZoom, kScrollZoom] THEN
  215.             IF vPt.v < vViewRect.top THEN
  216.                 DoScroll(uVHdl, InUpButton)
  217.             ELSE IF vPt.v > vViewRect.bottom THEN
  218.                 DoScroll(uVHdl, InDownButton);
  219.         SetClip(vOldClip);
  220.         DisposeRgn(vOldClip);
  221.         DoAutoScroll := TRUE;
  222.     END; {DoAutoScroll}
  223.  
  224. {----------------------------------------}
  225.     PROCEDURE InitAutoScroll (oDoc: TDocument);
  226.     BEGIN
  227.         IF oDoc.fDocType = kTextDoc THEN
  228.             SetClikLoop(@DoAutoScroll, oDoc.fTextHdl)
  229.         ELSE IF oDoc.fDocType = kPictDoc THEN
  230.             ;    {Install Autoscroll for graphics}
  231.     END; {InitAutoScroll}
  232.  
  233. {----------------------------------------}
  234.     PROCEDURE TScrollBar.SetupAutoScroll (vSBars: Integer);
  235.     BEGIN
  236.         oDoc := self.oDocument;
  237.         uSBars := vSBars;
  238.         uScrollDelay := 0;
  239.         CASE GetCRefCon(fCtlHdl) OF
  240.             kHBar: 
  241.                 uHHdl := fCtlHdl;
  242.             kVBar: 
  243.                 uVHdl := fCtlHdl;
  244.         END;
  245.         IF vSBars IN [kHScroll, kHScrollZoom] THEN
  246.             uVHdl := NIL;
  247.         IF vSBars IN [kVScroll, kVScrollZoom] THEN
  248.             uHHdl := NIL;
  249.     END; {SetupAutoScroll}
  250.  
  251. {----------------------------------------}
  252.     FUNCTION AdjustToCR (vTextHdl: TEHandle): Integer;
  253.         VAR
  254.             vCharHdl: CharsHandle;
  255.  
  256.     BEGIN
  257.         WITH vTextHdl^^ DO
  258.             BEGIN
  259.                 AdjustToCR := 0;
  260.                 vCharHdl := CharsHandle(hText);
  261.                 IF teLength > 0 THEN
  262.                     IF vCharHdl^^[teLength - 1] = Chr(kCR) THEN
  263.                         AdjustToCR := lineHeight;
  264.             END;
  265.     END; {AdjustToCR}
  266.  
  267. {-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -}
  268.     PROCEDURE TScrollBar.Adjust;
  269.         VAR
  270.             vViewWidth: Integer;
  271.             vViewHeight: Integer;
  272.             vCtlValue: Integer;
  273.             vCtlMax: Integer;
  274.             vScrollFlag: BOOLEAN;
  275.  
  276.     BEGIN
  277.         oDoc := self.oDocument;
  278.         WITH oDocument DO
  279.             IF fDocType = kTextDoc THEN
  280.                 BEGIN
  281.                     WITH fViewRect DO
  282.                         BEGIN
  283.                             vViewWidth := (right - left) - kTextMargin;
  284.                             vViewHeight := (bottom - top);
  285.                         END;
  286.                     WITH fTextHdl^^.selRect DO
  287.                         CASE GetCRefCon(fCtlHdl) OF
  288.                             kHBar: 
  289.                                 BEGIN
  290.                                     vCtlMax := self.ScrollMax(kHBar, 0);
  291.                                     SetCtlMax(fCtlHdl, vCtlMax);
  292.                                     vScrollFlag := (left < fViewRect.left) OR (right > fViewRect.right);
  293.                                     IF vScrollFlag THEN
  294.                                         BEGIN
  295.                                             IF left < -20000 THEN
  296.                                                 left := -20000;
  297.                                             vCtlValue := left - fDocRect.left - vViewWidth;
  298.                                             SetCtlValue(fCtlHdl, vCtlValue);
  299.                                             ScrollContent(fCtlHdl);
  300.                                         END;
  301.                                 END;
  302.                             kVBar: 
  303.                                 BEGIN
  304.                                     vCtlMax := self.ScrollMax(kVBar, AdjustToCR(fTextHdl));
  305.                                     SetCtlMax(fCtlHdl, vCtlMax);
  306.                                     vScrollFlag := (top < fViewRect.top) OR (bottom > fViewRect.bottom);
  307.                                     vScrollFlag := vScrollFlag OR (fDocRect.bottom < fViewRect.bottom);
  308.                                     IF vScrollFlag THEN
  309.                                         BEGIN
  310.                                             vCtlValue := bottom - fDocRect.top - vViewHeight;
  311.                                             SetCtlValue(fCtlHdl, vCtlValue);
  312.                                             ScrollContent(fCtlHdl);
  313.                                         END;
  314.                                 END;
  315.                         END;
  316.                 END
  317.             ELSE IF fDocType = kPictDoc THEN
  318.                 ;    {Code for graphics}
  319.     END; {Adjust}
  320.  
  321. {----------------------------------------}
  322.     PROCEDURE TScrollBar.ReDraw (vRect: Rect);
  323.         VAR
  324.             vDelta: Integer;
  325.             vDocRect: Rect;
  326.  
  327.     BEGIN
  328.         HideControl(fCtlHdl);
  329.         WITH vRect, oDocument DO
  330.             CASE GetCRefCon(fCtlHdl) OF
  331.                 kHBar: 
  332.                     BEGIN
  333.                         MoveControl(fCtlHdl, left, top);
  334.                         SizeControl(fCtlHdl, right, bottom);
  335.                         SetCtlMax(fCtlHdl, ScrollMax(kHBar, 0));
  336.                         vDelta := GetCtlMax(fCtlHdl) + fDocRect.left - fViewRect.left;
  337.                         IF vDelta < 0 THEN
  338.                             BEGIN
  339.                                 vDocRect := fDocRect;
  340.                                 OffsetRect(vDocRect, -vDelta, 0);
  341.                                 fDocRect := vDocRect;
  342.                             END;
  343.                     END;
  344.                 kVBar: 
  345.                     BEGIN
  346.                         MoveControl(fCtlHdl, left, top);
  347.                         SizeControl(fCtlHdl, right, bottom);
  348.                         SetCtlMax(fCtlHdl, ScrollMax(kVBar, 0));
  349.                         vDelta := GetCtlMax(fCtlHdl) + fDocRect.top - fViewRect.top;
  350.                         IF vDelta < 0 THEN
  351.                             BEGIN
  352.                                 vDocRect := fDocRect;
  353.                                 OffsetRect(vDocRect, 0, -vDelta);
  354.                                 fDocRect := vDocRect;
  355.                             END;
  356.                     END;
  357.             END;
  358.         ShowControl(fCtlHdl);
  359.     END; {ReDraw}
  360.  
  361. {----------------------------------------}
  362.     PROCEDURE TScrollBar.Activate;
  363.     BEGIN
  364.         IF BitAnd(gEvent.modifiers, activeFlag) <> 0 THEN
  365.             HiliteControl(fCtlHdl, 0)
  366.         ELSE
  367.             HiliteControl(fCtlHdl, 255);
  368.     END; {Activate}
  369.  
  370. END.    {unit StdScroll}
  371. {***********************************}